local RoomBase = require 'packages.chess-games.nchess.core.roombase'

---@class NChess.Client: NChess.RoomBase, ClientBase
local Client = RoomBase:subclass("NChess.Client")
local Ch = require "packages.chess-games.nchess"

Client:include(Fk.Base.ClientBase)

local ClientPlayer = require "packages.chess-games.nchess.client.clientplayer"

function Client:initialize(_client)
  RoomBase.initialize(self)
  Fk.Base.ClientBase.initialize(self, _client)

  self.clientplayer_klass = ClientPlayer

  self:addCallback("NChess.SyncBoard", self.syncBoard, true)
  self:addCallback("NChess.MovePieceTo", self.handleMovePieceTo)
  self:addCallback("NChess.PlayChess", self.playChess, true)
  self:addCallback("NChess.PrintPiece", self.handlePrintPiece)
  self:addCallback("NChess.AddPieceTo", self.handleAddPieceTo, true)
end

function Client:syncBoard(data)
  self.board = data
end

function Client:playSound(type)
  self:notifyUI("NChess.PlaySound", type)
end

function Client:handleMovePieceTo(data)
  local pieceId, fromX, fromY, x, y = data[1], data[2], data[3], data[4], data[5]
  local result = self:movePieceTo(pieceId, fromX, fromY, x, y) or {}
  if Ch:isChecking(self.board, pieceId > 0 and "white" or "black") then
    self:playSound("check")
  else
    self:playSound("play")
  end

  if result.type then
    if result.type == "castling" then
      local promotionData = result.data
      self:notifyUI("NChess.MovePieceTo", { pieceId, fromX, fromY, x, y })
      self:notifyUI("NChess.MovePieceTo", { promotionData.rookId, promotionData.fromX, promotionData.fromY, promotionData.x, promotionData.y })
    elseif result.type == "en_passant" then
      local passedData = result.data
      self:notifyUI("NChess.MovePieceTo", { pieceId, fromX, fromY, x, y })
      self:notifyUI("NChess.MovePieceOut", { passedData.pawnId, passedData.fromX, passedData.fromY })
    end
  else
    self:notifyUI("NChess.MovePieceTo", { pieceId, fromX, fromY, x, y })
  end
  self:notifyUI("NChess.UpdatePEN", self.getPENCode(self))
  self:updateLastMove(Self.role, fromX, fromY, x, y)
end

function Client:playChess(data)
  self:setupRequestHandler(Self, "NChess.PlayChess", data)
end

function Client:sendDataToUI(data)
  self:notifyUI("NChess.SyncBoard", self.board)
end

function Client:handlePrintPiece(data)
  local name, color, id = data[1], data[2], data[3]
  local piece = RoomBase.printPiece(self, name, color, id)
  self:notifyUI("NChess.UpdateNewPiece", { piece.id, piece.name })
end

function Client:handleAddPieceTo(data)
  local pieceId, x, y = data[1], data[2], data[3]
  RoomBase.addPieceTo(self, pieceId, x, y)
  if Ch:isChecking(self.board, pieceId > 0 and "white" or "black") then
    self:playSound("check")
  end
end

function Client:updateLastMove(pieceId, fromX, fromY, x, y)
  self:notifyUI("NChess.UpdateLastMove", { pieceId, fromX, fromY, x, y })
end

return Client
